//
// Created by jsz on 2021/6/10.
//
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include "device.h"

typedef struct {
    int chan_fd;
    protocol_resolver_t *proto_resolver;
    int pasitive_send;
} fake_device_t;

static fake_device_t dev;


void signal_handler(int signum)
{
    // 收到SIGUSR1，开始被动接收
    if (signum == SIGUSR1) {
        dev.pasitive_send = 1;
    }

    // 收到SIGUSR2, 开始主动发送
    if (signum == SIGUSR2) {
        dev.pasitive_send = 0;
    }
}

int register_signal_handler() {
    signal(SIGUSR1, signal_handler);
    signal(SIGUSR2, signal_handler);
    return 1;
}


int device_init(const char *channel, const char *protocol)
{
    // 以server方式打开
    dev.chan_fd = channel_open_passive(channel);
    if (dev.chan_fd < 0) {
        assert(0);
    }

    // 初始化协议
    dev.proto_resolver = protocol_init(protocol);
    if (!dev.proto_resolver) {
        assert(0);
    }

    // 注册信号处理器
    if (!register_signal_handler()) {
        assert(0);
    }

    dev.pasitive_send = 1;

    return 1;
}

/*
 * 延迟
 * 控制上、下限
 */
void delay_seconds(int interval)
{
    if (interval < 5)
        interval = 5;
    if (interval > 30)
        interval = 30;
    printf("send signal in %d seconds ...\n", interval);
    sleep(interval);
}

int device_run(int interval)
{
    int old_ch, ch;
    int recv_len, send_len;
    char recv_buff[MAX_FRAME_LEN], send_buff[MAX_FRAME_LEN];

    if ((ch = channel_wait(dev.chan_fd)) > 0) {
        for (;;) {
            // 被动发
            if (dev.pasitive_send) {
                if ((recv_len = channel_read(ch, recv_buff, MAX_FRAME_LEN)) <= 0) {
                    channel_close(ch);
                }
                else {
                    if ((send_len = dev.proto_resolver->get_resp(recv_buff, recv_len, send_buff, MAX_FRAME_LEN, dev.proto_resolver)) > 0) {
                        channel_write(ch, send_buff, send_len);
                    }
                }
            }
            else {  // 主动发
                if ((send_len = dev.proto_resolver->get_next_req(send_buff, MAX_FRAME_LEN, dev.proto_resolver)) > 0) {
                    print_frame("send req", send_buff, send_len);
                    if (channel_write(ch, send_buff, send_len) > 0) {
                        if ((recv_len = channel_read(ch, recv_buff, MAX_FRAME_LEN)) > 0) {
                            if (!dev.proto_resolver->is_valid_resp(recv_buff, recv_len, dev.proto_resolver)) {
                                printf("xxxxxx invalid resp\n");
                            }
                        }
                    }
                }
            }

            // 延时，方便进行信号控制
            delay_seconds(interval);
        }
    }

    printf("channel_wait failed\n");
    return 0;
}


void device_destroy()
{
    if (dev.proto_resolver) {
        protocol_destroy(dev.proto_resolver);
    }
    if (dev.chan_fd > 0) {
        channel_close(dev.chan_fd);
    }
}